package com.example.designhbwxz.book.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.example.designhbwxz.book.constant.EnumConstants;
import com.example.designhbwxz.book.factory.RegisterLoginComponentFactory;
import com.example.designhbwxz.book.pojo.UserInfo;
import com.example.designhbwxz.book.repo.UserRepository;
import com.example.designhbwxz.book.service.AbstractRegisterLoginFunc;
import com.example.designhbwxz.book.service.RegisterLoginFuncInterface;
import com.example.designhbwxz.book.utils.HttpClientUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 桥接者模式实现类二（实现类里边儿一定要去调父抽象类中的公共方法！这个坑了我 20 分钟）
 * <p/>
 * 第三方登陆【Gitee】实现类
 *
 * @author shenzw
 * @date 2023/10/28
 */
@Service
public class RegisterLoginByGitee extends AbstractRegisterLoginFunc implements RegisterLoginFuncInterface {

    @Value("${gitee.state}")
    private String giteeState;

    @Value("${gitee.token.url}")
    private String giteeTokenUrl;

    @Value("${gitee.user.url}")
    private String giteeUserUrl;

    @Value("${gitee.user.prefix}")
    private String giteeUserPrefix;

    @Autowired
    private UserRepository userRepository;

    /**
     * 初始化 funMap
     */
    @PostConstruct
    private void initFunMap() {
        RegisterLoginComponentFactory.funcMap.put(EnumConstants.GITEE.getCode(), this);
    }

    /**
     * 第三方账号登陆接口
     *
     * @param request HttpServletRequest
     * @return String
     */
    @Override
    public String login3rd(HttpServletRequest request) {

        String code = request.getParameter("code");
        String state = request.getParameter("state");
        // 进行 state 判断，state 的值是前端与后端商定好的，前端将 state 传给 Gitee 平台，Gitee 平台回传 state 给回调接口
        if (!giteeState.equals(state)) {
            return "invalid state！";
        }

        // 请求 Gitee 平台获取 Token，并携带 code
        String tokenUrl = giteeTokenUrl.concat(code);
        JSONObject tokenResponse = HttpClientUtils.execute(tokenUrl, HttpMethod.POST);
        String token = tokenResponse.getString("access_token");

        // 请求用户信息并携带 Token
        String userUrl = giteeUserUrl.concat(token);
        JSONObject userInfoResponse = HttpClientUtils.execute(userUrl, HttpMethod.GET);

        // 获取用户信息，userName 添加前缀 GITEE@，密码保持与 userName 一致，
        String userName = giteeUserPrefix.concat(userInfoResponse.getString("name"));

        // 自动注册和登陆功能，此处体现了方法的复用
        return autoRegister3rdAndLogin(userName, userName);
    }

    /**
     * 自动注册和登陆功能（这里没改调用父抽象类的公共方法，坑了我 20 分钟！）
     *
     * @param userName 用户名
     * @param password 密码
     * @return String
     */
    private String autoRegister3rdAndLogin(String userName, String password) {
        // 如果第三方账号已经登陆过了，则直接登陆
        if (super.commonCheckUserExists(userName, userRepository)) {
            return super.commonLogin(userName, password, userRepository);
        }

        // 如果没有登陆过
        // 组装用户信息
        UserInfo userInfo = UserInfo.builder()
                .userName(userName)
                .userPassword(password)
                .createDate(new Date())
                .build();

        // 到这一步说明第三方账号是第一次登陆，先进行注册
        super.commonRegister(userInfo, userRepository);

        // 自动注册完成后进行登陆
        return super.commonLogin(userName, password, userRepository);
    }
}
